package de.gameduell.framework.game.matching {
	import de.polygonal.ds.Array2;		

	/**
	 * @author cbra
	 */
	public class MatchingTools {
		
		/*
		 * deadlock check for matching games with tokenswaping
		 * works only with GenTiles
		 */
		public static function checkPossibleMove(playfield:Array2,matcher:Matcher):ITile {
			var possibleMoveTile:GenTile = null;
			for each(var tile:GenTile in playfield.toArray().reverse()){
				if(tile != null){
					var neighbours:Array = tile.getNeighbours();
					if(neighbours != null){
						for each (var neighbour:GenTile in neighbours){
							if(tile.token != null && neighbour.token != null){
								tile.swapTokens(neighbour);
								if(matcher.findMatchesNear(tile).length>0){
									possibleMoveTile = neighbour;
								}
								
								if(matcher.findMatchesNear(neighbour).length>0){
									possibleMoveTile = tile;
								}
								tile.swapTokens(neighbour);
							}
						}
					}
				}
			}
			return possibleMoveTile;
		}
			
		public static function setNeighbours(playfield:Array2):void{
			for(var col:int = 0;col < playfield.width;col++) {
				for(var row:int = 0;row < playfield.height;row++ ){	
					var tile:GenTile = playfield.get(col, row);
					tile.leftNeighbour = (col- 1) < 0 ? null : playfield.get((col- 1), row);
					tile.rightNeighbour = (col + 1) < playfield.width ? playfield.get((col + 1), row) : null;
					tile.upNeighbour = (row - 1) < 0 ? null : playfield.get(col, (row - 1));
					tile.downNeighbour =  (row + 1) < playfield.height ? playfield.get(col, (row + 1)) : null;
				}
			}
		}
		
		public static function shuffleTokens(playfield:Array2):void{
			var tokens:Array = getTokens(playfield).sort(randomSort);
			var tiles:Array  = getTilesWithToken(playfield);
			for each(var tile:GenTile in tiles){
				tile.token = tokens.shift();
			}
		}
		
		public static function getTokens(playfield:Array2):Array{
			var tokens:Array = new Array();
			for each(var tile:GenTile in playfield.getArray()) {
				if(tile.token != null){
					tokens.push(tile.token);
				}
				
			}
			return tokens;
		}
		
		public static function getTilesAround(tile:ITile):Array{
			var result:Array = new Array();
			var cleanResult:Array = new Array();
			result.push(tile.upNeighbour);
			result.push(tile.downNeighbour);
			result.push(tile.rightNeighbour);
			result.push(tile.leftNeighbour);
			if(tile.upNeighbour != null){
				result.push(tile.upNeighbour.rightNeighbour);
				result.push(tile.upNeighbour.leftNeighbour);
			}
			if(tile.downNeighbour != null){
				result.push(tile.downNeighbour.rightNeighbour);
				result.push(tile.downNeighbour.leftNeighbour);
			}
			for each(var resultTile:ITile in result){
				if(resultTile != null){
					cleanResult.push(resultTile);
				}
			}
			
			return cleanResult;
		}
		
		public static function getTilesWithToken(playfield:Array2):Array{
			var tiles:Array = new Array();
			for each(var tile:GenTile in playfield.getArray()) {
				if(tile.token != null){
					tiles.push(tile);
				}
				
			}
			return tiles;
		}
		
		public static function isEmptyColumn(col:Array):Boolean {
			for(var row:int = 0;row < col.length;row++) {
				var tile:GenTile = col[row];
				if(tile.token != null) {			
					return false;
				}
			}
			return true;
		}
		
		public static function countEmptyColumns(playfield:Array2):int{
			var emptyColumnNum:int = 0;
			for(var i:int = 0;i<playfield.width;i++){
				if(isEmptyColumn(playfield.getCol(i))){
					emptyColumnNum++;
				}
			}
			return emptyColumnNum;
		}

		private static function randomSort(a:Object, b:Object):Number {
			a;b;
			if(Math.random() > 0.5) {
				return 1;
			} else {
				return -1;
			} 
		}
	}
}
